"""
试卷管理 - API序列化器
定义序列化器模块：试卷管理相关数据转换
"""
from rest_framework import serializers
from django.contrib.auth import get_user_model
from django.utils import timezone
from decimal import Decimal

from .models import (
    ExamPaperTemplate, ExamPaper, PaperSection, PaperQuestion,
    PaperAnalysis, PaperVersion
)

User = get_user_model()


class ExamPaperTemplateSerializer(serializers.ModelSerializer):
    """试卷模板序列化器"""
    creator_name = serializers.CharField(source='creator.real_name', read_only=True)
    template_type_display = serializers.CharField(source='get_template_type_display', read_only=True)
    usage_count_display = serializers.SerializerMethodField()

    class Meta:
        model = ExamPaperTemplate
        fields = [
            'id', 'name', 'description', 'template_type', 'template_type_display',
            'template_config', 'default_duration', 'default_total_score',
            'default_passing_score', 'usage_count', 'usage_count_display',
            'creator', 'creator_name', 'is_active', 'is_public',
            'created_at', 'updated_at'
        ]
        read_only_fields = ['creator', 'usage_count', 'created_at', 'updated_at']

    def get_usage_count_display(self, obj):
        """获取使用次数显示"""
        return f"{obj.usage_count}次"

    def validate_template_config(self, value):
        """验证模板配置"""
        if not isinstance(value, dict):
            raise serializers.ValidationError("模板配置必须是字典格式")
        return value

    def validate(self, data):
        """验证数据"""
        default_score = data.get('default_total_score')
        passing_score = data.get('default_passing_score')

        if default_score and passing_score and passing_score > default_score:
            raise serializers.ValidationError("及格分不能超过总分")

        return data


class ExamPaperSerializer(serializers.ModelSerializer):
    """试卷序列化器"""
    creator_name = serializers.CharField(source='creator.real_name', read_only=True)
    template_name = serializers.CharField(source='template.name', read_only=True)
    paper_type_display = serializers.CharField(source='get_paper_type_display', read_only=True)
    status_display = serializers.CharField(source='get_status_display', read_only=True)
    generation_method_display = serializers.CharField(source='get_generation_method_display', read_only=True)
    reviewer_name = serializers.CharField(source='reviewer.real_name', read_only=True)

    class Meta:
        model = ExamPaper
        fields = [
            'id', 'title', 'description', 'template', 'template_name',
            'paper_type', 'paper_type_display', 'question_config',
            'duration', 'total_score', 'passing_score', 'status',
            'status_display', 'generation_method', 'generation_method_display',
            'questions', 'question_count', 'average_difficulty',
            'tags', 'creator', 'creator_name', 'reviewer', 'reviewer_name',
            'reviewed_at', 'review_notes', 'usage_count', 'is_public',
            'created_at', 'updated_at'
        ]
        read_only_fields = [
            'creator', 'reviewer', 'reviewed_at', 'usage_count',
            'question_count', 'average_difficulty', 'created_at', 'updated_at'
        ]

    def validate_question_config(self, value):
        """验证题目配置"""
        if not isinstance(value, dict):
            raise serializers.ValidationError("题目配置必须是字典格式")
        return value

    def validate_questions(self, value):
        """验证题目列表"""
        if not isinstance(value, list):
            raise serializers.ValidationError("题目列表必须是列表格式")
        return value

    def validate_tags(self, value):
        """验证标签"""
        if not isinstance(value, list):
            raise serializers.ValidationError("标签必须是列表格式")
        return value

    def validate(self, data):
        """验证数据"""
        total_score = data.get('total_score')
        passing_score = data.get('passing_score')

        if total_score and passing_score and passing_score > total_score:
            raise serializers.ValidationError("及格分不能超过总分")

        # 状态变更验证
        if self.instance:
            old_status = self.instance.status
            new_status = data.get('status', old_status)

            if old_status == 'archived' and new_status != 'archived':
                raise serializers.ValidationError("已归档的试卷不能修改状态")

            if new_status == 'published' and old_status != 'reviewed':
                raise serializers.ValidationError("只有已审核的试卷才能发布")

        return data


class PaperSectionSerializer(serializers.ModelSerializer):
    """试卷部分序列化器"""
    question_count = serializers.SerializerMethodField()

    class Meta:
        model = PaperSection
        fields = [
            'id', 'exam_paper', 'name', 'description', 'instructions',
            'section_config', 'start_question', 'end_question',
            'question_count', 'section_score', 'time_limit', 'order',
            'created_at', 'updated_at'
        ]
        read_only_fields = ['created_at', 'updated_at']

    def get_question_count(self, obj):
        """获取题目数量"""
        return obj.question_count

    def validate_section_config(self, value):
        """验证部分配置"""
        if not isinstance(value, dict):
            raise serializers.ValidationError("部分配置必须是字典格式")
        return value

    def validate(self, data):
        """验证数据"""
        start_q = data.get('start_question')
        end_q = data.get('end_question')

        if start_q and end_q and start_q > end_q:
            raise serializers.ValidationError("开始题号不能大于结束题号")

        return data


class PaperQuestionSerializer(serializers.ModelSerializer):
    """试卷题目序列化器"""
    question_info = serializers.SerializerMethodField()
    section_name = serializers.CharField(source='section.name', read_only=True)

    class Meta:
        model = PaperQuestion
        fields = [
            'id', 'exam_paper', 'section', 'section_name', 'question',
            'question_info', 'question_number', 'score', 'question_config',
            'order', 'created_at', 'updated_at'
        ]
        read_only_fields = ['created_at', 'updated_at']

    def get_question_info(self, obj):
        """获取题目信息"""
        question = obj.question
        return {
            'id': question.id,
            'title': question.title,
            'type': question.type,
            'difficulty': question.difficulty,
            'content': question.content[:100] + '...' if len(question.content) > 100 else question.content
        }

    def validate_question_config(self, value):
        """验证题目配置"""
        if value and not isinstance(value, dict):
            raise serializers.ValidationError("题目配置必须是字典格式")
        return value


class PaperAnalysisSerializer(serializers.ModelSerializer):
    """试卷分析序列化器"""
    exam_paper_title = serializers.CharField(source='exam_paper.title', read_only=True)
    analysis_status_display = serializers.CharField(source='get_analysis_status_display', read_only=True)

    class Meta:
        model = PaperAnalysis
        fields = [
            'id', 'exam_paper', 'exam_paper_title', 'difficulty_distribution',
            'average_difficulty', 'knowledge_coverage', 'coverage_score',
            'type_distribution', 'quality_score', 'discrimination_index',
            'estimated_time', 'improvement_suggestions', 'analysis_status',
            'analysis_status_display', 'analyzed_at', 'created_at', 'updated_at'
        ]
        read_only_fields = [
            'exam_paper', 'analyzed_at', 'created_at', 'updated_at'
        ]


class PaperVersionSerializer(serializers.ModelSerializer):
    """试卷版本序列化器"""
    exam_paper_title = serializers.CharField(source='exam_paper.title', read_only=True)
    created_by_name = serializers.CharField(source='created_by.real_name', read_only=True)

    class Meta:
        model = PaperVersion
        fields = [
            'id', 'exam_paper', 'exam_paper_title', 'version_number',
            'version_notes', 'paper_snapshot', 'changes', 'created_by',
            'created_by_name', 'is_current', 'created_at', 'updated_at'
        ]
        read_only_fields = ['created_by', 'created_at', 'updated_at']

    def validate_paper_snapshot(self, value):
        """验证试卷快照"""
        if not isinstance(value, dict):
            raise serializers.ValidationError("试卷快照必须是字典格式")
        return value

    def validate_changes(self, value):
        """验证变更记录"""
        if value and not isinstance(value, list):
            raise serializers.ValidationError("变更记录必须是列表格式")
        return value


class ExamPaperCreateSerializer(serializers.Serializer):
    """试卷创建序列化器"""
    title = serializers.CharField(max_length=200)
    description = serializers.CharField(required=False, allow_blank=True)
    paper_type = serializers.ChoiceField(
        choices=[
            ('formal', '正式考试'),
            ('practice', '练习考试'),
            ('mock', '模拟考试'),
            ('diagnostic', '诊断考试'),
        ],
        default='formal'
    )
    template_id = serializers.IntegerField(required=False)
    question_config = serializers.DictField(required=False, default=dict)
    duration = serializers.IntegerField(min_value=1, max_value=720)
    total_score = serializers.DecimalField(max_digits=6, decimal_places=2, min_value=1)
    passing_score = serializers.DecimalField(max_digits=6, decimal_places=2, min_value=0)
    tags = serializers.ListField(required=False, default=list)
    generation_method = serializers.ChoiceField(
        choices=[
            ('manual', '手动创建'),
            ('auto', '自动生成'),
            ('template', '模板生成'),
            ('ai', 'AI生成'),
        ],
        default='manual'
    )

    def validate_total_score(self, value):
        """验证总分"""
        if value <= 0:
            raise serializers.ValidationError("总分必须大于0")
        return value

    def validate_passing_score(self, value):
        """验证及格分"""
        if value < 0:
            raise serializers.ValidationError("及格分不能为负数")
        return value

    def validate(self, data):
        """验证数据"""
        total_score = data.get('total_score')
        passing_score = data.get('passing_score')

        if total_score and passing_score and passing_score > total_score:
            raise serializers.ValidationError("及格分不能超过总分")

        return data


class ExamPaperAutoGenerateSerializer(serializers.Serializer):
    """试卷自动生成序列化器"""
    template_id = serializers.IntegerField()
    question_bank_id = serializers.IntegerField(required=False)
    title = serializers.CharField(max_length=200, default='自动生成试卷')
    config = serializers.DictField(required=False, default={})

    def validate_template_id(self, value):
        """验证模板ID"""
        try:
            ExamPaperTemplate.objects.get(id=value)
            return value
        except ExamPaperTemplate.DoesNotExist:
            raise serializers.ValidationError("模板不存在")


class PaperAnalysisRequestSerializer(serializers.Serializer):
    """试卷分析请求序列化器"""
    paper_id = serializers.IntegerField()
    analysis_types = serializers.ListField(
        child=serializers.ChoiceField(choices=['difficulty', 'coverage', 'quality']),
        required=False,
        default=['difficulty', 'coverage', 'quality']
    )

    def validate_paper_id(self, value):
        """验证试卷ID"""
        try:
            ExamPaper.objects.get(id=value)
            return value
        except ExamPaper.DoesNotExist:
            raise serializers.ValidationError("试卷不存在")


class PaperVersionCreateSerializer(serializers.Serializer):
    """试卷版本创建序列化器"""
    version_number = serializers.CharField(max_length=20)
    version_notes = serializers.CharField(required=False, allow_blank=True)
    changes = serializers.ListField(required=False, default=[])

    def validate_changes(self, value):
        """验证变更记录"""
        if value and not isinstance(value, list):
            raise serializers.ValidationError("变更记录必须是列表格式")
        return value


class PaperCloneSerializer(serializers.Serializer):
    """试卷克隆序列化器"""
    name = serializers.CharField(max_length=200)
    description = serializers.CharField(required=False, allow_blank=True)


class PaperPublishSerializer(serializers.Serializer):
    """试卷发布序列化器"""
    publish_notes = serializers.CharField(required=False, allow_blank=True)


class PaperBulkActionSerializer(serializers.Serializer):
    """试卷批量操作序列化器"""
    paper_ids = serializers.ListField(child=serializers.IntegerField())
    action = serializers.ChoiceField(choices=['publish', 'archive', 'delete'])
    reason = serializers.CharField(required=False, allow_blank=True)

    def validate_paper_ids(self, value):
        """验证试卷ID列表"""
        if not value:
            raise serializers.ValidationError("请选择试卷")
        return value